<?php
namespace BLL\DAO;
use Illuminate\Support\Facades\File as File;

class StatBuilder{

    private static $cal_file_name;
    private static $find_val;
    private static $assign_val;
    private static $template;
    private static $templateFilePath;

    public static function createStatFinder($filename){
        //find file
        $jsonObj= self::readFromFile($filename);
        self::$cal_file_name = "Cal".$filename;
        //read value
        $tableName = $jsonObj['paramName'];
        $required_fields = $jsonObj['req_fields'];
        $suppied_fields = $jsonObj['sup_fields'];
        //create file
        self::createQuery( $tableName,$suppied_fields, $required_fields);
        self::createFile();
    }

    private static function readFromFile($configName=null){
        $path = str_replace("\\", DIRECTORY_SEPARATOR, $GLOBALS["AppConfig"]["statistics"]);
        $path = str_replace("/", DIRECTORY_SEPARATOR, $path); 
        if (!strrchr($path, DIRECTORY_SEPARATOR)) {
            $path = $path . DIRECTORY_SEPARATOR;
        }
        $filename= \app_path()."\\".$path.$configName.".json";
            if(file_exists($filename)){
                $str = file_get_contents($filename);
                $jsonObject = json_decode($str,true);
                return $jsonObject;
            }
    }
    private static function createFile(){
        self::$template = self::loadTemplate();
        $newFilePath = self::$templateFilePath.self::$cal_file_name.".php";
        self::setTemplate("{name}",self::$cal_file_name);
        self::setTemplate("{find}",self::$find_val);
        self::setTemplate("{asign}",self::$assign_val);
        File::put($newFilePath,self::$template);
    }
    private static function loadTemplate(){
        self::$templateFilePath = app_path().
                DIRECTORY_SEPARATOR.
                $GLOBALS["AppConfig"]["dataprocessor"].
                DIRECTORY_SEPARATOR;
        $FilePath = self::$templateFilePath."DataProcessorTemplate.tpl";
        return self::$template = file_get_contents($FilePath);
    }
    
    private static function setTemplate($item, $value){
        self::$template = \str_replace($item, $value , self::$template);
    }    
    private static function createQuery($tableName,$suppied_fields, $required_fields){
        for($i=0;$i<sizeof($suppied_fields);$i++){
            $sppname[$i] = $suppied_fields[$i]["name"];        
            isset($suppied_fields[$i]["node"])?         $sppnode[$i]    = $suppied_fields[$i]["node"]."()":$sppnode[$i] = null;           
            isset($suppied_fields[$i]["field"])?        $sppfield[$i]   = $suppied_fields[$i]["field"]:$sppfield[$i] = null;           
            isset($suppied_fields[$i]["aggregates"])?   $sppagg[$i]     = $suppied_fields[$i]["aggregates"]:$sppagg[$i] = null;           
        }
        for($i=0;$i<sizeof($required_fields);$i++){
            $reqname[$i] = $required_fields[$i]["name"];        
            isset($required_fields[$i]["node"])?         $reqnode[$i]   = $required_fields[$i]["node"]."()":$reqnode[$i] = null;           
            isset($required_fields[$i]["field"])?        $reqfield[$i]  = $required_fields[$i]["field"]:$reqfield[$i] = null;           
            isset($required_fields[$i]["aggregates"])?   $reqagg[$i]    = $required_fields[$i]["aggregates"]:$reqagg[$i] = null;  
        }
        $result = self::findField($sppname,$sppnode,$sppfield,$sppagg);
        foreach($result as $name=>$command){
            self::$find_val[] = "\$$name=$command";
        } 
        self::$find_val[] = self::combineValue($tableName,$sppname,$reqname,$reqfield,$reqagg);
        self::$assign_val =self::setField($reqname,$reqnode,$reqfield,$reqagg);
        self::$find_val = implode ("",self::$find_val);
        self::$assign_val = implode ("",self::$assign_val);
    }
    private static function findField($sppname,$sppnode,$sppfield,$sppagg){
        for($i=0;$i<sizeof($sppname);$i++){
            if(is_null($sppagg[$i])){
               is_null($sppnode[$i])?  $result[$sppname[$i]] = "\$ap->$sppfield[$i];\n\t":$result[$sppname[$i]] ="\$ap->$sppnode[$i]->$sppfield[$i];\n\t";
            }
            else if(is_null($sppnode[$i])){
               $result[$sppname[$i]] = "\$ap->$sppagg[$i]('$sppfield[$i]');\n\t";
            }
            else if(is_null($sppfield[$i])){
               $result[$sppname[$i]] = "\$ap->$sppnode[$i]->$sppagg[$i]();\n\t";
            }
             
            else $result[$sppname[$i]] = "\$ap->$sppnode[$i]->$sppagg[$i]('$sppfield[$i]');\n\t";
        }
        return $result;
    }
    private static function combineValue($tableName,$sppname,$reqname,$reqfield,$reqagg){
        $reqname_len = sizeof($reqname);
        $result[]="\n\t\$result = DB::table('".$tableName."')";
        foreach($sppname as $value){
            $result[]="\n\t\t\t->where('$value','=',$$value)";
        }
        for($i=0;$i<$reqname_len;$i++){
            $result[]="->$reqagg[$i]('$reqfield[$i]')";
            //last aggragate is select
        }
          if($reqagg[$reqname_len-1] === "select"){  
                $result[]="->get();";
            }
        $result = implode ("",$result);
        return $result;
    }
    private static function setField($reqname,$reqnode,$reqfield){
        for($i=0;$i<sizeof($reqname);$i++){
            isset($reqnode[$i])? $result[] = "\t\n\t\$ap->$reqnode[$i]->$reqname[$i]=\$result[\$i]->$reqfield[$i];":$result[] ="\$ap->$reqname[$i]=\$result[\$i]->$reqfield[$i];";
        }
        return $result;
    }

   
}
